package org.linlinjava.litemall.core.notify;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.Validate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.audience.AudienceTarget;

/**
 * 收银端消息推送
 * 
 * @author kretz
 *
 * @versoin 2020年12月28日
 */
@Component
public class PosPushSender {

	private static final Logger LOG = LoggerFactory.getLogger(PosPushSender.class);
	
	private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

	@Value("${litemall.pos.jpush.secret}")
	private String posSecret;

	@Value("${litemall.pos.jpush.appKey}")
	private String posAppKey;

	@Value("${litemall.kitchen.jpush.secret}")
	private String kitchenSecret;

	@Value("${litemall.kitchen.jpush.appKey}")
	private String kitchenAppKey;

	private JPushClient posJPushClient;

	private JPushClient kitchenJPushClient;
	
	@PostConstruct
	public void init() {
		this.posJPushClient = new JPushClient(posSecret, posAppKey);
		this.kitchenJPushClient = new JPushClient(kitchenSecret, kitchenAppKey);
	}

	/**
	 * 推送至pos
	 * @param shopId	店铺id，可以为null，null则推送所有店铺
	 * @param type		业务类型
	 * @param extras	根据type而定，为不同业务的附加参数
	 */
	public void pushPos(Integer shopId, Integer type, Object extras) {
		Validate.notNull(type);
		
		try {
			PushPayload pushPayload = buildPushObject(shopId, type, extras);
			posJPushClient.sendPush(pushPayload);
		} catch (APIConnectionException | APIRequestException e) {
			LOG.error("pos push error", e);
		}
	}

	/**
	 * 推送厨房制作端
	 * @param shopId	店铺id，可以为null，null则推送所有店铺
	 * @param type		业务类型
	 * @param extras	根据type而定，为不同业务的附加参数
	 */
	public void pushKitchen(Integer shopId, Integer type, Object extras) {
		Validate.notNull(type);
		
		try {
			PushPayload pushPayload = buildPushObject(shopId, type, extras);
			kitchenJPushClient.sendPush(pushPayload);
		} catch (APIConnectionException | APIRequestException e) {
			LOG.error("pos push error", e);
		}
	}

	/**
	 * 推送pos与厨房制作端
	 * @param shopId	店铺id，可以为null，null则推送所有店铺
	 * @param type		业务类型
	 * @param extras	根据type而定，为不同业务的附加参数
	 */
	public void pushAll(Integer shopId, Integer type, Object extras) {
		Validate.notNull(type);
		
		try {
			PushPayload pushPayload = buildPushObject(shopId, type, extras);
			posJPushClient.sendPush(pushPayload);
			kitchenJPushClient.sendPush(pushPayload);
		} catch (APIConnectionException | APIRequestException e) {
			LOG.error("pos push error", e);
		}
	}
	
	private static PushPayload buildPushObject(Integer shopId, Integer type, Object extras) {
		String msg = getMessage(shopId, type, extras);
        return PushPayload.newBuilder()
                .setPlatform(Platform.all())
                .setAudience(Audience.newBuilder()
                        .addAudienceTarget(AudienceTarget.tag(shopId.toString()))
                        .build())
                .setMessage(Message.newBuilder()
                        .setMsgContent(msg)
                        .build())
                .build();
    }
	
	private static String getMessage(Integer shopId, Integer type, Object extras) {
		String msgContentStr = null;
		try {
			PosPushMessageContent messageContent = new PosPushMessageContent(shopId, type, extras);
			msgContentStr = OBJECT_MAPPER.writeValueAsString(messageContent);
		} catch (JsonProcessingException e) {
			LOG.error("pos push error", e);
		}
		
        return msgContentStr;
    }
	
	/**
	 * pos推送消息内容
	 * @author kretz
	 *
	 * @versoin 2020年12月29日
	 */
	public static class PosPushMessageContent {
		
		// 店铺id，如果为null则所有店铺有效 
		private Integer shopId;
		
		// 推送业务类型
		private Integer type;
		
		// 额外参数，根据不同的业务而定
		private Object extras;
		
		private PosPushMessageContent(Integer shopId, Integer type, Object extras) {
			this.shopId = shopId;
			this.type = type;
			this.extras = type;
		}

		public Integer getShopId() {
			return shopId;
		}

		public void setShopId(Integer shopId) {
			this.shopId = shopId;
		}

		public Integer getType() {
			return type;
		}

		public void setType(Integer type) {
			this.type = type;
		}

		public Object getExtras() {
			return extras;
		}

		public void setExtras(Object extras) {
			this.extras = extras;
		}
		
	}

}
